﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Script.Serialization;
using System.Data;
using System.Collections;
using System.Reflection;

namespace ZX.EHR.Web
{
    public class JSONHelper
    {
        /// <summary>
        /// 类对像转换成json格式
        /// </summary> 
        /// <returns></returns>
        public static string ToJson(object t)
        {
            try
            {
                return new JavaScriptSerializer().Serialize(t);
            }
            catch
            {
                return new JavaScriptSerializer().Serialize(null);
            }
        }

        /// <summary>
        /// json格式转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strJson"></param>
        /// <returns></returns>
        public static T FromJson<T>(string strJson) where T : class
        {
            return new JavaScriptSerializer().Deserialize<T>(strJson);
        }

        /// <summary>
        /// DataTable转JSON
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string DataTableToJson(DataTable dt)
        {
            if (dt == null)
            {
                return "[]";
            }
            StringBuilder builder = new StringBuilder();
            builder.Append("[");
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    builder.Append("{");
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        builder.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + ToJson(dt.Rows[i][j]));
                        if (j < (dt.Columns.Count - 1))
                        {
                            builder.Append(",");
                        }
                    }
                    builder.Append("}");
                    if (i < (dt.Rows.Count - 1))
                    {
                        builder.Append(",");
                    }
                }
            }
            builder.Append("]");
            return builder.ToString();
        }

        /// <summary>
        /// 将泛型List转换为JSON
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public static string ListToJSON<T>(List<T> entitys)
        {
            //检查实体集合不能为空
            if (entitys == null || entitys.Count < 1)
            {
                return "[]";
            }
            StringBuilder builder = new StringBuilder();
            builder.Append("[");
            //取出第一个实体的所有Propertie
            Type entityType = entitys[0].GetType();
            PropertyInfo[] entityProperties = entityType.GetProperties();
            for (int j = 0; j < entitys.Count; j++)
            {
                builder.Append("{");
                //检查所有的的实体都为同一类型
                if (entitys[j].GetType() != entityType)
                {
                    return "[]";
                }
                for (int i = 0; i < entityProperties.Length; i++)
                {
                    object o = entityProperties[i].GetValue(entitys[j], null);
                    builder.Append("\"" + entityProperties[i].Name + "\":" + ToJson(o));
                    if (i < (entityProperties.Length - 1))
                    {
                        builder.Append(",");
                    }
                }
                builder.Append("}");
                if (j < (entitys.Count - 1))
                {
                    builder.Append(",");
                }
            }
            builder.Append("]");
            return builder.ToString();
        }

        /// <summary>
        /// 获取树格式对象的JSON
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <param name="id">ID的字段名</param>
        /// <param name="pid">PID的字段名</param>
        /// <returns></returns>
        public static string GetArrayJSON(DataTable dt, string id, string pid)
        {
            var list = DataTableToHashList(dt);
            var o = ArrayToTreeData(list, id, pid);
            return ToJson(o);
        }


        /// <summary>
        /// 获取树格式对象
        /// </summary>
        /// <param name="list">线性数据</param>
        /// <param name="id">ID的字段名</param>
        /// <param name="pid">PID的字段名</param>
        /// <returns></returns>
        public static object ArrayToTreeData(IList<Hashtable> list, string id, string pid)
        {
            var h = new Hashtable(); //数据索引 
            var r = new List<Hashtable>(); //数据池,要返回的 
            foreach (var item in list)
            {
                if (!item.ContainsKey(id)) continue;
                h[item[id].ToString()] = item;
            }
            foreach (var item in list)
            {
                if (!item.ContainsKey(id)) continue;
                if (!item.ContainsKey(pid) || item[pid] == null || !h.ContainsKey(item[pid].ToString()))
                {
                    r.Add(item);
                }
                else
                {
                    var pitem = h[item[pid].ToString()] as Hashtable;
                    if (!pitem.ContainsKey("children"))
                        pitem["children"] = new List<Hashtable>();
                    var children = pitem["children"] as List<Hashtable>;
                    children.Add(item);
                }
            }
            return r;
        }

        /// <summary>
        /// 将db reader转换为Hashtable列表
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        private static List<Hashtable> DataTableToHashList(DataTable dt)
        {
            var list = new List<Hashtable>();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                var item = new Hashtable();
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    var name = dt.Columns[j].Caption;
                    var value = dt.Rows[i][j].ToString();
                    item[name] = value;
                }
                list.Add(item);
            }
            return list;
        }
    }
}
